(function($) {

$.extend({
        metadata : {
                defaults : {
                        type: 'class',
                        name: 'metadata',
                        cre: /({.*})/,
                        single: 'metadata'
                },
                setType: function( type, name ){
                        this.defaults.type = type;
                        this.defaults.name = name;
                },
                get: function( elem, opts ){
                        var settings = $.extend({},this.defaults,opts);
                        // check for empty string in single property
                        if ( !settings.single.length ) settings.single = 'metadata';
                        
                        var data = $.data(elem, settings.single);
                        // returned cached data if it already exists
                        if ( data ) return data;
                        
                        data = "{}";
                        
                        if ( settings.type == "class" ) {
                                var m = settings.cre.exec( elem.className );
                                if ( m )
                                        data = m[1];
                        } else if ( settings.type == "elem" ) {
                                if( !elem.getElementsByTagName )
                                        return undefined;
                                var e = elem.getElementsByTagName(settings.name);
                                if ( e.length )
                                        data = $.trim(e[0].innerHTML);
                        } else if ( elem.getAttribute != undefined ) {
                                var attr = elem.getAttribute( settings.name );
                                if ( attr )
                                        data = attr;
                        }
                        
                        if ( data.indexOf( '{' ) <0 )
                        data = "{" + data + "}";
                        
                        data = eval("(" + data + ")");
                        
                        $.data( elem, settings.single, data );
                        return data;
                }
        }
});

/**
 * Returns the metadata object for the first member of the jQuery object.
 *
 * @name metadata
 * @descr Returns element's metadata object
 * @param Object opts An object contianing settings to override the defaults
 * @type jQuery
 * @cat Plugins/Metadata
 */
$.fn.metadata = function( opts ){
        return $.metadata.get( this[0], opts );
};

})(jQuery);
